package mymyoux.io
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	
	import mymyoux.signals.Signal;
	
	import org.osmf.utils.URL;
	/**
	 * Distant file loader binary or text
	 */
	public class URLFile
	{
		/**
		 * URLRequest
		 */
		private var _urlRequest:URLRequest;
		/**
		 * URLLoader
		 */
		private var _urlLoader:URLLoader;
		/**
		 * @private
		 */
		private var _signalError:Signal;
		/**
		 * @private
		 */
		private var _signalData:Signal;
		/**
		 * @private
		 */
		private var _signalProgress:Signal;
		/**
		 * Create a URLFile Object
		 * @param url URL of the file
		 * @param params Parameters
		 */
		public function URLFile(url:String, params:Array = null)
		{
			_signalData = new Signal(Object);
			_signalError = new Signal(Event);
			_signalProgress = new Signal(Number);
			_urlRequest = new URLRequest(url);
			if(params != null && params.length > 0)
			{
				var variables:URLVariables = new URLVariables();
				var p:String;
				for(p in params)
				{
					variables[p] = params[p];
				}
				_urlRequest.data = variables;
			}
			_urlLoader = new URLLoader();
			_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
			_urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
			_urlLoader.addEventListener(Event.COMPLETE, onComplete);
			_urlLoader.addEventListener(ProgressEvent.PROGRESS, onProgress);
		}
		/**
		 * Dispatches loaded data 
		 * Signal(Object);
		 */
		public function get signalData():Signal
		{
			return _signalData;
		}

		public function set signalData(value:Signal):void
		{
			_signalData = value;
		}
		
		/**
		 * Dispatches errors
		 * Signal(Event);
		 */
		public function get signalError():Signal
		{
			return _signalError;
		}

		public function set signalError(value:Signal):void
		{
			_signalError = value;
		}
		
		/**
		 * Dispatches progress
		 * Signal(Number); with 0 &lt;= Number &lt;= 100
		 */
		public function get signalProgress():Signal
		{
			return _signalProgress;
		}
		
		public function set signalProgress(value:Signal):void
		{
			_signalProgress = value;
		}
		/**
		 * Start loading
		 */
		public function load():void
		{
			_urlLoader.load(_urlRequest);
		
		}
		/**
		 * Called by the URLLoader when the loading is completed
		 * @param event Event
		 */ 
		private function onComplete(event:Event):void
		{
			try
			{
				_signalData.dispatch(_urlLoader.data);
			}catch(error:TypeError)
			{
				trace("Error loading:"+this);
			}
		}
		/**
		 * Called by the URLLoader when the loading has error
		 * @param event Error
		 */ 
		private function onError(event:Event):void
		{
			_signalError.dispatch(event);
		}
		/**
		 * Called by the URLLoader during the loading
		 * @param event Event
		 */ 
		private function onProgress(event:ProgressEvent):void
		{
			var pourcent:Number = 0;
			if(event.bytesLoaded > 0 && event.bytesTotal > 0)
			{
				pourcent = event.bytesLoaded / event.bytesTotal * 100;
			}
			_signalProgress.dispatch(pourcent);
		}
		/**
		 * Convertit l'objet en chaine de caractères.
		 * @return	Une chaîne de caractères de la forme <code class="prettyprint">[ClasseObject paramètre1="valeur1" paramètre2="valeur2" ... ]</code> 
		 */
		public function toString():String
		{
			return "[URLFile url=\""+_urlRequest.url+"\" bytesTotal=\""+_urlLoader.bytesTotal+"\" bytesLoaded=\""+_urlLoader.bytesLoaded+"\"]";
		}
	}
}